package com.nf1000.balancelibrary;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothServerSocket;
import android.bluetooth.BluetoothSocket;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.UUID;

/**
 * Created by Jason on 2016/3/22.
 */
public class BluetoothChatService {
    private static final String TAG = "BluetoothChatService";
    private static final boolean D = true;
    private static final String NAME_SECURE = "BluetoothChatSecure";
    private static final String NAME_INSECURE = "BluetoothChatInsecure";
    private static final UUID MY_UUID_SECURE = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
    private static final UUID MY_UUID_INSECURE = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
    private final BluetoothAdapter mAdapter = BluetoothAdapter.getDefaultAdapter();
    private final Handler mHandler;
    private BluetoothChatService.AcceptThread mSecureAcceptThread;
    private BluetoothChatService.AcceptThread mInsecureAcceptThread;
    private BluetoothChatService.ConnectThread mConnectThread;
    private BluetoothChatService.ConnectedThread mConnectedThread;
    public static int mState;
    public static final int STATE_NONE = 0;
    public static final int STATE_LISTEN = 1;
    public static final int STATE_CONNECTING = 2;
    public static final int STATE_CONNECTED = 3;

    public BluetoothChatService(Context context, Handler handler) {
        mState = 0;
        this.mHandler = handler;
    }

    private synchronized void setState(int state) {
        Log.d("BluetoothChatService", "setState() " + mState + " -> " + state);
        mState = state;
        if(this.mHandler != null) {
            this.mHandler.obtainMessage(1, state, -1).sendToTarget();
        }

    }

    public synchronized int getState() {
        return mState;
    }

    public synchronized void start() {
        Log.d("BluetoothChatService", "start");

        try {
            if(this.mConnectThread != null) {
                this.mConnectThread.cancel();
                this.mConnectThread = null;
            }

            if(this.mConnectedThread != null) {
                this.mConnectedThread.cancel();
                this.mConnectedThread = null;
            }

            this.setState(1);
            if(this.mSecureAcceptThread == null) {
                this.mSecureAcceptThread = new BluetoothChatService.AcceptThread(true);
                this.mSecureAcceptThread.start();
            }

            if(this.mInsecureAcceptThread == null) {
                this.mInsecureAcceptThread = new BluetoothChatService.AcceptThread(false);
                this.mInsecureAcceptThread.start();
            }
        } catch (Exception var2) {
            Log.d("BluetoothChatService", "start excrption" + var2.getMessage());
        }

    }

    public synchronized void connect(BluetoothDevice device, boolean secure) {
        Log.d("BluetoothChatService", "connect to: " + device);

        try {
            if(mState == 2 && this.mConnectThread != null) {
                this.mConnectThread.cancel();
                this.mConnectThread = null;
            }

            if(this.mConnectedThread != null) {
                this.mConnectedThread.cancel();
                this.mConnectedThread = null;
            }

            this.mConnectThread = new BluetoothChatService.ConnectThread(device, secure);
            this.mConnectThread.start();
            this.setState(2);
        } catch (Exception var4) {
            this.connectionFailed();
        }

    }

    public boolean connectTest(BluetoothDevice device) {
        if(device == null) {
            return false;
        } else {
            try {
                BluetoothSocket bs = device.createRfcommSocketToServiceRecord(MY_UUID_INSECURE);
                if(bs != null) {
                    bs.connect();
                    bs.close();
                    return true;
                }
            } catch (Exception var3) {
                ;
            }

            this.connectionFailed();
            return false;
        }
    }

    public synchronized void connected(BluetoothSocket socket, BluetoothDevice device, String socketType) {
        Log.d("BluetoothChatService", "connected, Socket Type:" + socketType);

        try {
            if(this.mConnectThread != null) {
                this.mConnectThread.cancel();
                this.mConnectThread = null;
            }

            if(this.mConnectedThread != null) {
                this.mConnectedThread.cancel();
                this.mConnectedThread = null;
            }

            if(this.mSecureAcceptThread != null) {
                this.mSecureAcceptThread.cancel();
                this.mSecureAcceptThread = null;
            }

            if(this.mInsecureAcceptThread != null) {
                this.mInsecureAcceptThread.cancel();
                this.mInsecureAcceptThread = null;
            }

            this.mConnectedThread = new BluetoothChatService.ConnectedThread(socket, socketType);
            this.mConnectedThread.start();
            Message e = this.mHandler.obtainMessage(4);
            Bundle bundle = new Bundle();
            bundle.putString("device_name", device.getName());
            e.setData(bundle);
            this.mHandler.sendMessage(e);
            this.setState(3);
        } catch (Exception var6) {
            this.connectionFailed();
        }

    }

    public synchronized void stop() {
        Log.d("BluetoothChatService", "stop");

        try {
            if(this.mConnectThread != null) {
                this.mConnectThread.cancel();
                this.mConnectThread = null;
            }

            if(this.mConnectedThread != null) {
                this.mConnectedThread.cancel();
                this.mConnectedThread = null;
            }

            if(this.mSecureAcceptThread != null) {
                this.mSecureAcceptThread.cancel();
                this.mSecureAcceptThread = null;
            }

            if(this.mInsecureAcceptThread != null) {
                this.mInsecureAcceptThread.cancel();
                this.mInsecureAcceptThread = null;
            }

            this.setState(0);
        } catch (Exception var2) {
            ;
        }

    }

    public boolean write(byte[] out) {
        try {
            BluetoothChatService.ConnectedThread r;
            synchronized(this) {
                if(mState != 3) {
                    return false;
                }

                r = this.mConnectedThread;
            }

            r.write(out);
        } catch (Exception var5) {
            ;
        }

        return true;
    }

    private void connectionFailed() {
        Message msg = this.mHandler.obtainMessage(5);
        Bundle bundle = new Bundle();
        bundle.putString("toast", "Unable to connect device");
        msg.setData(bundle);
        this.mHandler.sendMessage(msg);
        this.start();
    }

    private void connectionLost() {
        Message msg = this.mHandler.obtainMessage(5);
        Bundle bundle = new Bundle();
        bundle.putString("toast", "Device connection was lost");
        msg.setData(bundle);
        this.mHandler.sendMessage(msg);
        this.start();
    }

    private class AcceptThread extends Thread {
        private final BluetoothServerSocket mmServerSocket;
        private String mSocketType;

        public AcceptThread(boolean secure) {
            secure = true;
            BluetoothServerSocket tmp = null;
            this.mSocketType = secure?"Secure":"Insecure";

            try {
                if(secure && BluetoothChatService.this.mAdapter != null && BluetoothChatService.this.mAdapter.isEnabled()) {
                    tmp = BluetoothChatService.this.mAdapter.listenUsingRfcommWithServiceRecord("BluetoothChatSecure", BluetoothChatService.MY_UUID_SECURE);
                }
            } catch (IOException var5) {
                Log.e("BluetoothChatService", "Socket Type: " + this.mSocketType + "listen() failed", var5);
            }

            this.mmServerSocket = tmp;
        }

        public void run() {
            Log.d("BluetoothChatService", "Socket Type: " + this.mSocketType + "BEGIN mAcceptThread" + this);
            this.setName("AcceptThread" + this.mSocketType);
            BluetoothSocket socket = null;

            while(BluetoothChatService.mState != 3) {
                try {
                    if(this.mmServerSocket != null) {
                        socket = this.mmServerSocket.accept();
                    }
                } catch (Exception var6) {
                    Log.e("BluetoothChatService", "Socket Type: " + this.mSocketType + "accept() failed", var6);
                    break;
                }

                if(socket != null) {
                    BluetoothChatService e = BluetoothChatService.this;
                    synchronized(BluetoothChatService.this) {
                        switch(BluetoothChatService.mState) {
                            case 0:
                            case 3:
                                try {
                                    if(socket != null) {
                                        socket.close();
                                    }
                                } catch (Exception var4) {
                                    Log.e("BluetoothChatService", "Could not close unwanted socket", var4);
                                }
                                break;
                            case 1:
                            case 2:
                                BluetoothChatService.this.connected(socket, socket.getRemoteDevice(), this.mSocketType);
                        }
                    }
                }
            }

            Log.i("BluetoothChatService", "END mAcceptThread, socket Type: " + this.mSocketType);
        }

        public void cancel() {
            Log.d("BluetoothChatService", "Socket Type" + this.mSocketType + "cancel " + this);

            try {
                if(this.mmServerSocket != null) {
                    this.mmServerSocket.close();
                }
            } catch (Exception var2) {
                Log.e("BluetoothChatService", "Socket Type" + this.mSocketType + "close() of server failed", var2);
            }

        }
    }

    private class ConnectThread extends Thread {
        private final BluetoothSocket mmSocket;
        private final BluetoothDevice mmDevice;
        private String mSocketType;

        public ConnectThread(BluetoothDevice device, boolean secure) {
            secure = true;
            this.mmDevice = device;
            BluetoothSocket tmp = null;
            this.mSocketType = secure?"Secure":"Insecure";

            try {
                if(secure) {
                    tmp = device.createRfcommSocketToServiceRecord(BluetoothChatService.MY_UUID_SECURE);
                }
            } catch (Exception var6) {
                Log.e("BluetoothChatService", "Socket Type: " + this.mSocketType + "create() failed", var6);
            }

            this.mmSocket = tmp;
        }

        public void run() {
            Log.i("BluetoothChatService", "BEGIN mConnectThread SocketType:" + this.mSocketType);
            this.setName("ConnectThread" + this.mSocketType);

            try {
                if(BluetoothChatService.this.mAdapter != null) {
                    BluetoothChatService.this.mAdapter.cancelDiscovery();
                }

                if(this.mmSocket != null) {
                    this.mmSocket.connect();
                }

                Log.e("BluetoothChatService", "è¿žæŽ¥æˆ?åŠŸ:" + this.mmDevice.getName());
            } catch (IOException var5) {
                try {
                    Log.e("BluetoothChatService", this.mmDevice.getName());
                    if(this.mmSocket != null) {
                        this.mmSocket.close();
                    }
                } catch (IOException var3) {
                    Log.e("BluetoothChatService", "unable to close() " + this.mSocketType + " socket during connection failure", var3);
                }

                BluetoothChatService.this.connectionFailed();
                return;
            }

            BluetoothChatService e = BluetoothChatService.this;
            synchronized(BluetoothChatService.this) {
                BluetoothChatService.this.mConnectThread = null;
            }

            BluetoothChatService.this.connected(this.mmSocket, this.mmDevice, this.mSocketType);
        }

        public void cancel() {
            try {
                if(this.mmSocket != null) {
                    this.mmSocket.close();
                }
            } catch (IOException var2) {
                Log.e("BluetoothChatService", "close() of connect " + this.mSocketType + " socket failed", var2);
            }

        }
    }

    private class ConnectedThread extends Thread {
        private final BluetoothSocket mmSocket;
        private final InputStream mmInStream;
        private final OutputStream mmOutStream;

        public ConnectedThread(BluetoothSocket socket, String socketType) {
            Log.d("BluetoothChatService", "create ConnectedThread: " + socketType);
            this.mmSocket = socket;
            InputStream tmpIn = null;
            OutputStream tmpOut = null;

            try {
                tmpIn = socket.getInputStream();
                tmpOut = socket.getOutputStream();
            } catch (IOException var7) {
                Log.e("BluetoothChatService", "temp sockets not created", var7);
            }

            this.mmInStream = tmpIn;
            this.mmOutStream = tmpOut;
        }

        public void run() {
            Log.i("BluetoothChatService", "BEGIN mConnectedThread");
            byte[] buffer = new byte[1024];

            while(true) {
                try {
                    int bytes;
                    do {
                        while(this.mmInStream == null) {
                            ;
                        }

                        bytes = this.mmInStream.read(buffer);
                    } while(BluetoothChatService.this.mHandler == null);

                    BluetoothChatService.this.mHandler.obtainMessage(2, bytes, -1, buffer).sendToTarget();
                } catch (IOException var8) {
                    Log.e("BluetoothChatService", "disconnected", var8);
                    BluetoothChatService.this.connectionLost();

                    try {
                        if(this.mmInStream != null) {
                            this.mmInStream.close();
                        }
                    } catch (Exception var7) {
                        var7.printStackTrace();
                    }

                    try {
                        if(this.mmOutStream != null) {
                            this.mmOutStream.close();
                        }
                    } catch (Exception var6) {
                        var6.printStackTrace();
                    }

                    try {
                        if(this.mmSocket != null) {
                            this.mmSocket.close();
                        }
                    } catch (Exception var5) {
                        var5.printStackTrace();
                    }

                    BluetoothChatService.this.start();
                    return;
                }
            }
        }

        public void write(byte[] buffer) {
            try {
                if(this.mmOutStream != null) {
                    this.mmOutStream.write(buffer);
                    if(BluetoothChatService.this.mHandler != null) {
                        BluetoothChatService.this.mHandler.obtainMessage(3, -1, -1, buffer).sendToTarget();
                    }
                }
            } catch (IOException var3) {
                Log.e("BluetoothChatService", "Exception during write", var3);
            }

        }

        public void cancel() {
            try {
                if(this.mmSocket != null) {
                    this.mmSocket.close();
                }
            } catch (IOException var2) {
                Log.e("BluetoothChatService", "close() of connect socket failed", var2);
            }

        }
    }
}
